package com.lyxs916.common;


import android.util.SparseArray;

import com.lyxs916.corelib.core.application.Global;
import com.lyxs916.corelib.core.utils.gsonutils.GsonHelper;
import com.lyxs916.network.ApiService;
import com.lyxs916.progresscallback.ProgressCallBack;
import com.lyxs916.progresscallback.ProgressRequestBody;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;


/**
 * 说明:
 * 作者： 杨阳; 创建于：  2017-06-07  18:21
 */
public class HttpManager {

    /**
     * 默认的超时时间
     */
    private static final int DEFAULT_TIMEOUT = 30;
    /**
     * 加长的超时间
     */
    private static final int LONG_TIMEOUT = 200;
    /**
     * 网络请求对象
     */
    public Retrofit retrofit;
    /**
     * 请求的接口
     */
    public ApiService serviceApi;

    /**
     * 构建头部类型
     */
    private static HashMap<String, Integer> hashMap = new HashMap();

    /**
     * 构造方法私有，单例模式
     */
    public HttpManager(int hostType, ProgressCallBack progressCallBack, boolean isLongTimeOut) {
        retrofit = getRetrofitBuilder(hostType, progressCallBack, isLongTimeOut);
        serviceApi = retrofit.create(ApiService.class);
    }


    public Retrofit getRetrofit() {
        return retrofit;
    }
    private static SparseArray<HttpManager> sRetrofitManager = new SparseArray<>(HostType.TYPE_COUNT);

    /**
     * 生成Retrofit实例
     */
    private Retrofit getRetrofitBuilder(int hostType, ProgressCallBack progressCallBack, boolean isLongTimeOut) {
        return new Retrofit.Builder()
                .baseUrl(ApiConstants.getHost(hostType))
                .addConverterFactory(GsonConverterFactory.create(GsonHelper.getGson()))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .client(getOkHttpClientType(progressCallBack, isLongTimeOut))
                .build();

    }

    /**
     * 获取单例，默认头部类型
     *
     * @return HttpManager
     */
    public static HttpManager getInstance() {
        return getInstance(HostType.TYPE_DEFAULT, -1, null);
    }


    /**
     * 获取请求的实例
     *
     * @param hostType 主机类型
     * @param headType 头部类型
     * @param path     请求路径
     * @return HttpManager
     */
    public static HttpManager getInstance(@HostType.HostTypeChecker int hostType, int headType, String path) {

        return getInstance(hostType, headType, path, null, false);

    }

    /**
     * 获取请求的实例
     *
     * @param hostType         主机类型
     * @param headType         头部类型
     * @param path             请求路径
     * @param isLongTimeOut    是否带回调
     * @param progressCallBack 回调的接口
     * @return HttpManager
     */
    public static HttpManager getInstance(@HostType.HostTypeChecker int hostType, int headType, String path, ProgressCallBack progressCallBack, boolean isLongTimeOut) {
        HttpManager retrofitManager = sRetrofitManager.get(hostType);
        if (headType != -1) {
            hashMap.put(path, headType);
        }
        if (retrofitManager == null || (isLongTimeOut && progressCallBack != null)) {
            retrofitManager = new HttpManager(hostType, progressCallBack, isLongTimeOut);
            sRetrofitManager.put(hostType, retrofitManager);
            return retrofitManager;
        }
        return retrofitManager;
    }


    /**
     * 添加拦截器，增加添加头部
     *
     * @return
     */
    private OkHttpClient getOkHttpClientType(ProgressCallBack progressCallBack, boolean isLongTimeOut) {
        final OkHttpClient.Builder builder = getOkHttpClient(progressCallBack, isLongTimeOut);
        builder.addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                //获取请求
                Request oldRequest = chain.request();
                String str = oldRequest.url().encodedPath();
                Request request;
                int type = 0;
                if (hashMap.get(str) != null) {
                    type = hashMap.get(str).intValue();
                }
                //登录的头部类型
                if (type == HeadType.LOGIN_HEAD.getKey()) {
                    request = chain.request().newBuilder()
                            .addHeader("code", "35")
                            .addHeader("token", "57fff9bd3d6f35c5782e0a10b2469eb6")
                            .build();

                    //未登录头部类型
                } else if (type == HeadType.UNREGISTERED_HEAD.getKey()) {
                    request = chain.request().newBuilder()
                            .addHeader("ticket", "DDD")
                            .addHeader("secret", "EEE")
                            .build();

                    //默认头部类型
                } else {
                    request = chain.request().newBuilder()
//                            .addHeader("Cache-Control", "max-age=0")
//                            .addHeader("mac", "CCC")
//                            .addHeader("ticket", "DDD")
//                            .addHeader("secret", "EEE")
                            .build();
                }
                return chain.proceed(request);
            }
        }).build();

        return builder.build();

    }

    /**
     * 添加回调的拦截
     *
     * @param progressCallBack 回调的接口
     * @return Interceptor
     */
    private Interceptor getAddCallbackInterceptor(final ProgressCallBack progressCallBack) {

        Interceptor callbackInterceptor = new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {

                //增加请求的精度回调
                Request newRequest = chain.request().body() != null ?
                        chain.request().newBuilder().post(new ProgressRequestBody(chain.request().body(), progressCallBack)).build()
                        : chain.request();

                return chain.proceed(newRequest);
            }
        };


        return callbackInterceptor;
    }


    /**
     * 请求的一些设置
     *
     * @return OkHttpClient.Builder
     */
    public OkHttpClient.Builder getOkHttpClient(ProgressCallBack progressCallBack, boolean isLongTimeOut) {
        final OkHttpClient.Builder builder = new OkHttpClient.Builder();
        //1：手动创建一个OkHttpClient并设置超时时间
        builder.retryOnConnectionFailure(true);//链接失败重新链接
        builder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);//链接超时
        builder.readTimeout(isLongTimeOut ? LONG_TIMEOUT : DEFAULT_TIMEOUT, TimeUnit.SECONDS);//读取超时
        builder.writeTimeout(isLongTimeOut ? LONG_TIMEOUT : DEFAULT_TIMEOUT, TimeUnit.SECONDS);//写入超时
        if (progressCallBack != null) {
            builder.addNetworkInterceptor(getAddCallbackInterceptor(progressCallBack));
        }

        //设置缓存目录
        File cacheDirectory = new File(Global.appSDCachePath, "HttpCache");
        final Cache cache = new Cache(cacheDirectory, 50 * 1024 * 1024);//
        builder.cache(cache);//设置缓存
        return builder;
    }

    public OkHttpClient getOkHttpClient() {
        return (OkHttpClient) getRetrofit().callFactory();
    }
    /**
     * 设置接口类型
     *
     * @param headType 头部的类型
     * @param path     请求的路径
     */
    public synchronized void setHeadType(int headType, String path) {
        hashMap.put(path, headType);
    }

}

